string(TOLOWER ${ARITH} ARITH_PATH)

if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/low/${ARITH_PATH}/CMakeLists.txt")
	include("${CMAKE_CURRENT_SOURCE_DIR}/low/${ARITH_PATH}/CMakeLists.txt")
endif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/low/${ARITH_PATH}/CMakeLists.txt")

set(CORE_SRCS relic_core.c relic_rand.c relic_conf.c relic_pool.c relic_util.c)

string(TOLOWER ${ARCH} ARCH_PATH)
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/arch/relic_arch_${ARCH_PATH}.c")
	list(APPEND CORE_SRCS "arch/relic_arch_${ARCH_PATH}.c")
endif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/arch/relic_arch_${ARCH_PATH}.c")

file(GLOB BN_SRCS bn/*.c)
file(GLOB DV_SRCS dv/*.c)
file(GLOB FP_SRCS fp/*.c)
file(GLOB FB_SRCS fb/*.c)
file(GLOB FT_SRCS ft/*.c)
file(GLOB EP_SRCS ep/*.c)
file(GLOB EB_SRCS eb/*.c)
file(GLOB HB_SRCS hb/*.c)
file(GLOB PP_SRCS pp/*.c)
file(GLOB MD_SRCS md/*.c)

set(RELIC_SRCS ${CORE_SRCS})

if (CHECK)
	list(APPEND RELIC_SRCS "relic_error.c")
endif(CHECK)

if (TRACE)
	list(APPEND RELIC_SRCS "relic_trace.c")
endif(TRACE)	

if (TESTS GREATER 0)
	list(APPEND RELIC_SRCS "relic_test.c")
endif(TESTS GREATER 0)

if (BENCH GREATER 0)
	list(APPEND RELIC_SRCS "relic_bench.c")
endif(BENCH GREATER 0)

if (WITH_BN)
	list(APPEND RELIC_SRCS ${BN_SRCS})
	file(GLOB TEMP low/easy/relic_bn*.c)
	list(APPEND LOW_SRCS ${TEMP})
endif(WITH_BN)

if (WITH_DV)
	list(APPEND RELIC_SRCS ${DV_SRCS})
endif(WITH_DV)

if (WITH_FP)
	list(APPEND RELIC_SRCS ${FP_SRCS})
	file(GLOB TEMP low/easy/relic_fp*.c)
	list(APPEND LOW_SRCS ${TEMP})
endif(WITH_FP)

if (WITH_FB)
	list(APPEND RELIC_SRCS ${FB_SRCS})
	file(GLOB TEMP low/easy/relic_fb*.c)
	list(APPEND LOW_SRCS ${TEMP})
endif(WITH_FB)

if (WITH_FT)
	list(APPEND RELIC_SRCS ${FT_SRCS})
	file(GLOB TEMP low/easy/relic_ft*.c)
	list(APPEND LOW_SRCS ${TEMP})
endif(WITH_FT)

if (WITH_EP)
	list(APPEND RELIC_SRCS ${EP_SRCS})
endif(WITH_EP)

if (WITH_EB)
	list(APPEND RELIC_SRCS ${EB_SRCS})
endif(WITH_EB)

if (WITH_HB)
	list(APPEND RELIC_SRCS ${HB_SRCS})
endif(WITH_HB)

if (WITH_PP)
	file(GLOB TEMP low/easy/relic_pp*.c)
	list(APPEND LOW_SRCS ${TEMP})
	# Add all the extension code.
	file(GLOB TEMP fpx/*.c)
	list(APPEND PP_SRCS ${TEMP})
	file(GLOB TEMP epx/*.c)
	list(APPEND PP_SRCS ${TEMP})
	list(APPEND RELIC_SRCS ${PP_SRCS})
endif(WITH_PP)

# Pairings over binary fields are a special case.
if (WITH_PB)
	file(GLOB TEMP pb/relic_pb_map*.c)
	list(APPEND PB_SRCS ${TEMP})
	# Add all the extension code.
	file(GLOB TEMP fbx/*.c)
	list(APPEND PB_SRCS ${TEMP})
	# Add genus-1 or genus-2 pairings (or both).
	if (WITH_EB)
		file(GLOB TEMP pb/relic_pb_*1.c)
		list(APPEND PB_SRCS ${TEMP})
	endif(WITH_EB)
	if (WITH_HB)
		file(GLOB TEMP pb/relic_pb_*2.c)
		list(APPEND PB_SRCS ${TEMP})
	endif(WITH_HB)
	list(APPEND RELIC_SRCS ${PB_SRCS})
endif(WITH_PB)

if (WITH_CP)
	if (WITH_BN)
		list(APPEND RELIC_SRCS "cp/relic_cp_rsa.c")
		list(APPEND RELIC_SRCS "cp/relic_cp_rabin.c")
	endif(WITH_BN)
	if (WITH_EB OR WITH_EP)
		list(APPEND RELIC_SRCS "cp/relic_cp_ecdh.c")
		list(APPEND RELIC_SRCS "cp/relic_cp_ecmqv.c")
		list(APPEND RELIC_SRCS "cp/relic_cp_ecdsa.c")
		list(APPEND RELIC_SRCS "cp/relic_cp_ecss.c")
	endif(WITH_EB OR WITH_EP)
	if (WITH_PB OR WITH_PP)
		list(APPEND RELIC_SRCS "cp/relic_cp_sokaka.c")
		list(APPEND RELIC_SRCS "cp/relic_cp_bls.c")
		list(APPEND RELIC_SRCS "cp/relic_cp_bbs.c")
	endif(WITH_PB OR WITH_PP)
endif(WITH_CP)

if (WITH_MD)
	list(APPEND RELIC_SRCS ${MD_SRCS})
endif(WITH_MD)

foreach(SRC ${LOW_SRCS})
	get_filename_component(SRC ${SRC} NAME_WE)
	set(FILE "${CMAKE_CURRENT_SOURCE_DIR}/low/${ARITH_PATH}/${SRC}")
	if (EXISTS "${FILE}.c")
		list(APPEND ARITH_SRCS "${FILE}.c")
	endif(EXISTS "${FILE}.c")
	if (EXISTS "${FILE}.s")
		list(APPEND ARITH_ASMS "${FILE}.s")
	endif(EXISTS "${FILE}.s")
	if(NOT EXISTS "${FILE}.c" AND NOT EXISTS "${FILE}.s")
		list(APPEND ARITH_SRCS "low/easy/${SRC}.c")
	endif(NOT EXISTS "${FILE}.c" AND NOT EXISTS "${FILE}.s")
endforeach(SRC)

list(APPEND RELIC_SRCS ${ARITH_SRCS})

list(APPEND RELIC_SRCS ${ARITH_ASMS})
set_source_files_properties(${ARITH_ASMS} PROPERTIES LANGUAGE C COMPILE_FLAGS "-DASM -x assembler-with-cpp")

add_custom_target(arith_objs DEPENDS ${ARITH_OBJS})

macro(LINK_LIBS LIBRARY)
	if(OPSYS STREQUAL LINUX)
		target_link_libraries(${LIBRARY} rt)
	endif(OPSYS STREQUAL LINUX)
	if(MULTI)
		target_link_libraries(${LIBRARY} gomp m)
	endif(MULTI)
	if(TRACE)
		target_link_libraries(${LIBRARY} dl)
	endif(TRACE)
endmacro(LINK_LIBS)

if (SHLIB)
	add_library(relic SHARED ${RELIC_SRCS} ${ARITH_OBJS})
	add_dependencies(relic arith_objs)
	target_link_libraries(relic ${ARITH_LIBS})
	LINK_LIBS(relic)
endif(SHLIB)

if (STLIB)
	add_library(relic_s STATIC ${RELIC_SRCS} ${ARITH_OBJS})
	add_dependencies(relic_s arith_objs)
	target_link_libraries(relic_s ${ARITH_LIBS})
	LINK_LIBS(relic_s)
endif(STLIB)
